<template>
  <div>
    <div>=========================================</div>
    <h1>Vue3中，watch</h1>
    <div>需求：当前stopTestNum达到60时，停止监听stopTestNum</div>
    <div>测试停止监听的数据：{{ stopTestNum }}</div>
    <el-button type="primary" @click="changeStopTestNum">测试停止监听</el-button>
    <h1>Vue3中，watch和watchEffect的区别</h1>
    <div>需求：当前水温达到60℃时，或水位达到80cm时，给服务器发请求</div>
    <div>当前水温：{{ temp }}℃</div>
    <div>当前水位：{{ height }}cm</div>

    <el-button type="primary" @click="changeTemp">水温+10</el-button>
    <el-button type="primary" @click="changeHeight">水位+10</el-button>
    <div>=========================================</div>
  </div>
</template>

<!-- 安装vite-plugin-vue-setup-extend插件让<script setup>标签</script>可以直接自定义组件名 -->
<script setup lang="ts" name="WatchWatchEffect">
const stopTestNum = ref(0)
const temp = ref(10)
const height = ref(0)

const changeStopTestNum = () => {
  stopTestNum.value += 10
}
const changeTemp = () => {
  temp.value += 10
}
const changeHeight = () => {
  height.value += 10
}

/**
 * watch
 * watch函数的第一个参数是：被监视的数据
 * watch函数的第二个参数是：监视的回调
 * watch函数的第三个参数是：配置对象（deep、immediate、flush等）（flush：可以设置为 'pre'、'post' 或 'sync'，控制回调函数的执行时机。）
 *
 * watch需要指定监视的数据，指定的数据变化了就会执行回调函数，如下指定监视temp, height数据
 *
 * watch的知识点：
 * (1)watch函数会返回一个停止监听器（函数），也可以解构得到停止/暂停/恢复侦听器（函数）。
 * (2)若修改的是ref定义的对象中的属性，newValue和oldValue都是新值，因为它们是同一个对象。
 * (3)若修改整个ref定义的对象，newValue是新值，oldValue是旧值，因为不是同一个对象了。
 * (4)若监视的是reactive定义的对象，默认是开启深度监视的（隐式地创建了深度监听），且该深度监听是不可关闭的。
 * (5)监视ref或reactive定义的对象类型数据中的某个属性时需要注意：若该属性不是【对象类型】，需要写成函数形式；若该属性依然是【对象类型】，可以直接写，也可以写成函数形式，更建议写成函数形式。（若是对象，监视的是地址值；若需要关注对象内部，需要手动开启深度监视。）
 */
// const { stop, pause, resume } = watch(stopTestNum, (newV) => {})
const stopWatch = watch(stopTestNum, (newV) => {
  console.log("stopTestNum改变了", newV)
  if (newV >= 60) {
    console.log("stopTestNum达到60，停止stopTestNum的监听")
    stopWatch()
  }
})
// watch([temp, height], (newV) => {
//   const [newTemp, newHeight] = newV
//   console.log("newTemp, newHeight", newTemp, newHeight)
//   // 如果需要用到2个数据就要监听2个数据，那需要用到7个数据就要监听7个数据，感觉太臃肿，可以使用watchEffect
//   if (newTemp >= 60 || newHeight >= 80) {
//     console.log("watch给服务器发请求")
//   }
// })

/**
 * watchEffect
 * watchEffect不需要指定监视的数据，会自己收集并监视回调函数里使用到的响应式数据，使用到的数据只要一变化就会执行回调函数，比较智能
 * watchEffect会一开始就执行一次回调函数，相当于watch配置了immediate属性
 * watchEffect函数会返回一个停止监听器（函数），也可以解构得到停止/暂停/恢复侦听器（函数）。
 *
 * 注意：在watchEffect的回调函数中使用多个数据作为判断条件时，请先把所有条件数据都声明一次，这样做是为了明确指定这些条件数据都是
 * watchEffect要收集监听的依赖数据，不声明的话如果使用了“||”短路求值就会出现收集不到“||”后面条件的问题。
 */
watchEffect(() => {
  // 先把所有条件数据都声明一次，避免“||”条件判断时影响到watchEffect收集监听数据
  const t = temp.value
  const h = height.value
  // 不先声明数据直接的话，“||”会影响到watchEffect收集“||”后面条件
  // if (temp.value >= 60 || height.value >= 80) {
  if (t >= 60 || h >= 80) {
    console.log("watchEffect给服务器发请求")
  }
})
</script>

<style scoped></style>
